using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using MacomberMap.Common.Components;
using System.Data.Common;
using System.Windows.Forms;

namespace MacomberMap.Common.Types
{
    /// <summary>
    /// This class stores information on an element type
    /// </summary>
    public class MM_Element_Type : MM_Serializable, IComparable<MM_Element_Type>
    {
        #region Variable declarations
        /// <summary>The name of the element type</summary>
        private String _Name = "";

        /// <summary>Handle name changes to the element type, to trap the rare error</summary>
        public String Name
        {
            get { return _Name; }
            set
            {
                if (!String.IsNullOrEmpty(_Name) && value != _Name)
                {
                    Clipboard.Clear();
                    Clipboard.SetText("Macomber Map - element type name change located:\n" + Environment.StackTrace);
                    MessageBox.Show("An error has been located, whereby an element type name has been changed unintentionally. The stack trace has been copied to the clipboard. Please email this information to mlegatt@ercot.com. Thank you.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                _Name = value;
            }
        }

        /// <summary>The acroym (short name) for the element type</summary>
        public string Acronym;

        /// <summary>The name used to represent the type in CIM</summary>
        public string CIMName;

        /// <summary>The parameter needed to identify this object from CIM</summary>
        public string CIMParameter;

        /// <summary>Whether the user is allowed to view this element type</summary>
        public bool Permitted;

        /// <summary>
        /// The parameters used for our element
        /// </summary>
        public string ElementParameters
        {
            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    XmlDocument ReadDoc = new XmlDocument();
                    ReadDoc.LoadXml(value);
                    Configuration = ReadDoc.DocumentElement;
                }
            }
            get
            {
                if (Configuration == null)
                    return null;
                else
                    return Configuration.OuterXml;
            }
        }

        /// <summary>
        /// The XML configuration for this element
        /// </summary>
        public XmlElement Configuration=null;

        /// <summary>The integer value, used in the SQL versions of the CIM server</summary>
        public int Index;
        #endregion


        #region Initialization
        /// <summary>        
        /// Initialize a new element type
        /// </summary>
        /// <param name="Configuration">The XML configuration element</param>        
        public MM_Element_Type(XmlElement Configuration)
            : base(Configuration)
        {
            this.Configuration = Configuration;
            this.Name = Configuration.Attributes["Name"].Value;
            this.Acronym = Configuration.Attributes["Acronym"].Value;
            this.CIMName = Configuration.Attributes["CIMName"].Value;
        }


        /// <summary>        
        /// Initialize a new element type
        /// </summary>
        /// <param name="DbReader">The data row for the element</param>                
        public MM_Element_Type(DbDataReader DbReader)
            : base(DbReader)
        { }

        /// <summary>
        /// Initialize a new element type
        /// </summary>
        /// <param name="Name">The name of the element type</param>
        /// <param name="Acronym">The acronym for the element type</param>
        /// <param name="CIMName">The CIM name of the type</param>
        public MM_Element_Type(String Name, String Acronym, String CIMName)
        {
            this.Name = Name;
            this.Acronym = Acronym;
            this.CIMName = CIMName;
        }

        #endregion


        /// <summary>
        /// Return the element type name as a string
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this.Name;

        }

        
       /* #region Data connector linkages
        /// <summary>
        /// Add a linkage between this element type and its data table
        /// </summary>
        /// <param name="qConfig">The query configuration </param>
        /// <param name="qDs">The one-line data set</param>
        /// <param name="DbLinkage">The Xml configuration for the column to be added</param>
        /// <param name="Application">The application to hold the data point</param>
        /// <param name="IntegrationLayer">The data integration layer</param>
        public void AddTableLinkage(Query_Configuration qConfig, DataSet qDs, XmlElement DbLinkage, String Application, Data_Integration IntegrationLayer)
        {

            //Find the appropriate connector
            MM_DataConnector dbConn = IntegrationLayer.OptimalConnector(DbLinkage.ParentNode.Attributes["Connector"].Value);

            //Make sure our table already exists 
            if (!qDs.Tables.Contains(this.Name))
            {
                qDs.Tables.Add(Name);
                qDs.Tables[Name].CaseSensitive = false;
                qDs.Tables[Name].Columns.Add("Substation", typeof(String));
                qDs.Tables[Name].Columns.Add("Name", typeof(String));
                qDs.Tables[Name].Columns.Add("TEID", typeof(MM_Element));
                qDs.Tables[Name].Columns.Add("Voltage", typeof(String));
                qDs.Tables[Name].PrimaryKey = new DataColumn[] { qDs.Tables[Name].Columns[0], qDs.Tables[Name].Columns[1] };
            }


            dbConn.AddToQuery(qConfig, qDs, DbLinkage, Application, this.Name);

        }
        #endregion*/        
    
        #region IComparable<MM_Element_Type> Members
        /// <summary>
        /// Compare two element types
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo(MM_Element_Type other)
        {
            return Index.CompareTo(other.Index);
        }

        #endregion
    }

}
